#include "AT25F1024.h"

void AT25F1024_Init(void)
{
    SimulateSPI_Init();
    SimulateSPI_Stop();
}

/**
 * 写芯片使能(在指令或数据前先要使能)
 */
void AT25F1024_WriteEnable(void)
{
    SimulateSPI_Start();
    SimulateSPI_SwapByte(AT25F1024_CMD_WRITE_ENABLE);
    SimulateSPI_Stop();
}

/**
 * 等待操作完成
 */
void AT25F1024_WaitBusy(void)
{
    uint32_t i = 100000;
    SimulateSPI_Start();
    SimulateSPI_SwapByte(AT25F1024_CMD_READ_STATUS_REG);
    while ((SimulateSPI_SwapByte(0x00) & 0x01) == 1)
    {
        i--;
        if (i == 0)
        {
            break;
        }
    }
    SimulateSPI_Stop();
}

/**
 * 不能在Busy状态读;bit.0=1
 * 可以跨页读
 */
void AT25F1024_ReadBuffer(uint32_t addr, uint8_t *pBuffer, uint16_t len)
{
    uint16_t i = 0;
    SimulateSPI_Start();
    SimulateSPI_SwapByte(AT25F1024_CMD_READ_DATA); // 读数据cmd
    SimulateSPI_SwapByte((addr >> 16) & 0xFF);     // bit.23~bit.16
    SimulateSPI_SwapByte((addr >> 8) & 0xFF);      // bit.15~bit.8
    SimulateSPI_SwapByte((addr)&0xFF);             // bit.7~bit.0
    for (i = 0; i < len; i++)
    {
        pBuffer[i] = SimulateSPI_SwapByte(0x00);
    }
    SimulateSPI_Stop();
}

/**
 * @note Page-Size(256Byte)
 * @attention addr(不能跨页);
 */
void AT25F1024_WriteBuffer(uint32_t addr, uint8_t *pBuffer, uint16_t len)
{
    uint16_t i = 0;
    AT25F1024_WriteEnable(); //
    SimulateSPI_Start();
    SimulateSPI_SwapByte(AT25F1024_CMD_WRITE_DATA); // 写数据cmd
    SimulateSPI_SwapByte((addr >> 16) & 0xFF);      // bit.23~bit.16
    SimulateSPI_SwapByte((addr >> 8) & 0xFF);       // bit.15~bit.8
    SimulateSPI_SwapByte((addr)&0xFF);              // bit.7~bit.0
    for (i = 0; i < len; i++)
    {
        SimulateSPI_SwapByte(pBuffer[i]);
    }
    SimulateSPI_Stop();
    AT25F1024_WaitBusy();
}

/**
 * 扇区擦除
 * 只有Flash存储空间数据为0xFF时才能修改Flash的数据，所以每次写入前需要进行擦除。
 */
void AT25F1024_EraseSector(uint32_t addr)
{
    AT25F1024_WriteEnable(); //
    SimulateSPI_Start();
    SimulateSPI_SwapByte(AT25F1024_CMD_ERASE_SECTOR); // 写数据cmd
    SimulateSPI_SwapByte((addr >> 16) & 0xFF);        // bit.23~bit.16
    SimulateSPI_SwapByte((addr >> 8) & 0xFF);         // bit.15~bit.8
    SimulateSPI_SwapByte((addr)&0xFF);                // bit.7~bit.0
    SimulateSPI_Stop();
    AT25F1024_WaitBusy();
}

uint16_t AT25F1024_GetID(void)
{
    uint16_t result = 0x0000;
    uint8_t maker_code = 0;
    uint8_t chip_code = 0;
    SimulateSPI_Start();
    SimulateSPI_SwapByte(AT25F1024_CMD_READ_ID);
    maker_code = SimulateSPI_SwapByte(0xFF);
    chip_code = SimulateSPI_SwapByte(0xFF);
    SimulateSPI_Stop();
    result = (((uint16_t)maker_code) << 8) | chip_code;
    return result;
}
